/* Includes ------------------------------------------------------------------*/
#include "flash.h"

/* Private typedef -----------------------------------------------------------*/
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

/* Private define ------------------------------------------------------------*/
/* Define the STM32F10x FLASH Page Size depending on the used STM32 device */
#if defined (STM32F10X_HD) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL) || defined (STM32F10X_XL)
  #define FLASH_PAGE_SIZE    ((uint16_t)0x800)
#else
  #define FLASH_PAGE_SIZE    ((uint16_t)0x400)
#endif

#define BANK1_WRITE_START_ADDR  ((uint32_t)0x08008000)
#define BANK1_WRITE_END_ADDR    ((uint32_t)0x08008400)

#ifdef STM32F10X_XL
  #define BANK2_WRITE_START_ADDR   ((uint32_t)0x08088000)
  #define BANK2_WRITE_END_ADDR     ((uint32_t)0x0808C000)
#endif /* STM32F10X_XL */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint32_t EraseCounter = 0x00, Address = 0x00;
uint32_t Data = 0x3210ABCD;
uint32_t NbrOfPage = 0x00;
volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
volatile TestStatus MemoryProgramStatus = PASSED;

#ifdef STM32F10X_XL
volatile TestStatus MemoryProgramStatus2 = PASSED;
#endif /* STM32F10X_XL */

void writeFlash(bkp_timer d)
{
    /* Porgram FLASH Bank1 ********************************************************/
    /* Unlock the Flash Bank1 Program Erase controller */
    FLASH_UnlockBank1();

    /* Define the number of page to be erased */
    NbrOfPage = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FLASH_PAGE_SIZE;

    /* Clear All pending flags */
    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);

    /* Erase the FLASH pages */
    for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
    {
        FLASHStatus = FLASH_ErasePage(BANK1_WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter));
        if(FLASH_ErasePage(BANK1_WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter))!= FLASH_COMPLETE){
        	while(1){
        		lcd_error(clear);
        	}
        }
    }

    /* Program Flash Bank1 */
    Address = BANK1_WRITE_START_ADDR;
    uint32_t i = 0;

    while((Address < BANK1_WRITE_END_ADDR))
    {
    	if(FLASH_ProgramWord(Address, d.raw[i]) == FLASH_COMPLETE){
    		Address = Address + 4;
    		if(i < 256)
    			i++;
    	}
    	else{
    		while(1){
    			lcd_error(write);
    		}
    	}
    }

    FLASH_LockBank1();


}

void readFlash(){
/* Check the corectness of written data */
    Address = BANK1_WRITE_START_ADDR;
    uint32_t i = 0;
    while((Address < BANK1_WRITE_END_ADDR))
    {
    	Data = *(__IO uint32_t*)Address;
    	if(Data < 1){
    		MemoryProgramStatus = FAILED;
    	}
    	timer.raw[i] = Data;
    	Address += 4;
    	if(i <257)
    		i++;
    }
    if( MemoryProgramStatus == FAILED)
    {
    	if(timer.bkp.ciclo_ETAPA1 < 1)
    		timer.bkp.ciclo_ETAPA1 = 3;
    	if(timer.bkp.ciclo_ETAPA2 < 1)
    		timer.bkp.ciclo_ETAPA2 = 1;
    	if(timer.bkp.ciclo_ETAPA3 < 1)
    		timer.bkp.ciclo_ETAPA3 = 4;
    	if(timer.bkp.ciclo_ETAPA4 < 1)
    		timer.bkp.ciclo_ETAPA4 = 4;
    	if(timer.bkp.ciclo_ETAPA5 < 1)
    		timer.bkp.ciclo_ETAPA5 = 5;
    	if(timer.bkp.ciclo_ETAPA6 < 1)
    		timer.bkp.ciclo_ETAPA6 = 15;
    	if(timer.bkp.ciclo_ETAPA7 < 1)
    		timer.bkp.ciclo_ETAPA7 = 4;
    }
}
